#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include "SysLog.h"

bool SysLog_t::singleton;

SysLog_t::SysLog_t(const char *_indent) throw() : indent(_indent) {
		flog = stderr;

    		if( singleton ) {
                		emergency("%s\n", "DEBUG: There second log system initialized.");
		                exit(-1);
		}
        	singleton = true;
#ifndef NDEBUG
		FILE *t = fopen("log.log", "at");
		if( NULL == t ) {
				emergency("%s\n", "DEBUG: Can't open log file.");
				exit(-1);
		} else
				flog = t;
#endif
}

SysLog_t::~SysLog_t() throw() {
#ifndef NDEBUF
		fclose((FILE*)flog);
#endif
}

#define SysLog(level) {\
                va_list ap; \
                va_start(ap, format); \
                fprintf((FILE*)flog, "%s: %s: ", (indent), (level));\
                vfprintf((FILE*)flog, format, ap); \
                fprintf((FILE*)flog, "\n");\
                va_end(ap); \
        }

#define LOG_EMERG       "EMERG"
#define LOG_ALERT       "ALERT"
#define LOG_CRIT        "CRIT"
#define LOG_ERR         "ERR"
#define LOG_WARNING     "WARNING"
#define LOG_NOTICE      "NOTICE"
#define LOG_INFO        "INFO"
#define LOG_DEBUG       "DEBUG"

void SysLog_t::emergency(const char *format, ...) throw() {
		SysLog(LOG_EMERG)
		flush();
}

void SysLog_t::alert(const char *format, ...) throw()  {
		SysLog(LOG_ALERT)
		flush();
}

void SysLog_t::critical(const char *format, ...) throw()  {
		SysLog(LOG_CRIT)
		flush();
}

void SysLog_t::error(const char *format, ...) throw()  {
		SysLog(LOG_ERR)
		flush();
}

void SysLog_t::warning(const char *format, ...)  throw() SysLog(LOG_WARNING)
void SysLog_t::notice(const char *format, ...) throw() SysLog(LOG_NOTICE)
void SysLog_t::info(const char *format, ...) throw() SysLog(LOG_INFO)
void SysLog_t::debug(const char *format, ...) throw() SysLog(LOG_DEBUG)

void SysLog_t::flush()  throw() {
		fflush((FILE*)flog);
}

SysLog_t *log;

